﻿using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TeaCompiler.CodeDom {

    #region Statement

    /// <summary>
    /// 表示一个语句。
    /// </summary>
    public abstract class Statement : Node {

        /// <summary>
        /// 判断当前语句是否为空语句。
        /// </summary>
        public virtual bool IsEmpty {
            get {
                return false;
            }
        }

        //public override void GenerateC(IndentedTextWriter writer) {

        //}
    }

    /// <summary>
    /// 表示一个脚本块。 
    /// </summary>
    public class Block : Statement, IScope {

        /// <summary>
        /// 获取当前的全部语句。
        /// </summary>
        public List<Statement> Statements {
            get;
            set;
        }

        //Dictionary<string, TokenType> _maps;

        //public void AddSymbol(string name, TokenType declType) {

        //    if (_maps == null)
        //        _maps = new Dictionary<string, TokenType>();


        //    _maps[name] = declType;

        //}

        //public TokenType GetSymbol(string name) {
        //    return _maps[name];
        //}

        //IScopeNode IScopeNode.GetDefinedBlock(string name) {
        //    return GetDefinedBlock(name);
        //}

        ///// <summary>
        ///// 在当前块和父块搜索已经定义了变量名为 <paramref name="name"/> 的块。
        ///// </summary>
        ///// <param name="name">查找的名字。</param>
        ///// <returns>返回找到块。如果找不到返回 null 。</returns>
        //public Block GetDefinedBlock(string name) {
        //    for (BreakableStatement b = this; b != null; b = b.Parent) {
        //        Block target = b as Block;
        //        if (target != null && target._maps != null && target._maps.ContainsKey(name))
        //            return target;
        //    }
        //    return null;
        //}

        public override void Write(IndentedTextWriter writer) {
            writer.Write('{');
            writer.Indent++;

            foreach (Statement f in Statements) {
                writer.WriteLine();
                f.Write(writer);
            }

            writer.WriteLine();
            writer.Indent--;
            writer.Write('}');

        }

        //public override void Accept(IAstVisitor visitor) {
        //    visitor.VisitBlock(this);
        //}

        //NodeList<FunctionDeclaration> _fns;

        //public NodeList<FunctionDeclaration> Functions {
        //    get {

        //        if (_fns == null)
        //            _fns = new NodeList<FunctionDeclaration>();
        //        return _fns;
        //    }
        //}

        //public void AddFunction(FunctionDeclaration fn) {
        //    AddSymbol(fn.Name, TokenType.Var);

        //    Functions.Add(fn);
        //}

        //public override void GenerateC(IndentedTextWriter writer) {
        //    foreach (Statement s in Statements) {
        //        s.GenerateC(writer);
        //    }
        //}

        public Module Module {
            get {
                return null;
            }
        }

        public IScope Parent {
            get;
            set;
        }
    }

    /// <summary>
    /// 表示一个最终的模块。
    /// </summary>
    public class Module : Block, IScope {

        Module IScope.Module {
            get {
                return this;
            }
        }

        public override void Write(IndentedTextWriter writer) {
            foreach (Statement f in Statements) {
                writer.WriteLine();
                f.Write(writer);
            }
        }

        //public override void Accept(IAstVisitor visitor) {
        //    visitor.VisitModule(this);
        //}

    }

    /// <summary>
    /// 表示一个表达式语句。
    /// </summary>
    public class ExpressionStatement : Statement {

        /// <summary>
        /// 获取表达式。
        /// </summary>
        public Expression Expression {
            get;
            set;
        }

        public override Location StartLocation {
            get {
                return Expression.StartLocation;
            }
            set {
                Expression.StartLocation = value;
            }
        }

        public override Location EndLocation {
            get {
                return Expression.EndLocation;
            }
            set {
                Expression.EndLocation = value;
            }
        }

        public override bool IsEmpty {
            get {
                return Expression is EmptyExpression;
            }
        }

        public override void Write(IndentedTextWriter writer) {
            Expression.Write(writer);
        }

        //[System.Diagnostics.DebuggerStepThrough]
        //public override void Accept(IAstVisitor visitor) {
        //    visitor.VisitExpressionStatement(this);
        //}

        //public override void GenerateC(IndentedTextWriter writer) {
        //    Expression.GenerateC(writer);
        //    writer.Write(';');
        //}
    }

    /// <summary>
    /// 表示变量定义语句。
    /// </summary>
    public class VariableStatement : Statement {

        //public enum TypeStyle {
        //    None,
        //    Type,
        //    Const,
        //    Var,
        //}

        /// <summary>
        /// 变量定义节点。
        /// </summary>
        public class VariableDeclaration : Node {

            public Identifier Name {
                get;
                set;
            }

            public Expression Initialiser {
                get;
                set;
            }

            public override Location StartLocation {
                get {
                    return Name.StartLocation;
                }
            }

            public override Location EndLocation {
                get {
                    return Initialiser == null ? Name.EndLocation : Initialiser.EndLocation;
                }
            }

            public override void Write(IndentedTextWriter writer) {
                Name.Write(writer);
                if (Initialiser != null) {
                    writer.Write(" = ");
                    Initialiser.Write(writer);
                }
            }

            //public override void Accept(IAstVisitor visitor) {
            //    visitor.VisitVariableDeclaration(this);
            //}

            //public override void GenerateC(IndentedTextWriter writer) {
            //    Name.GenerateC(writer);

            //    if (Initialiser != null) {
            //        writer.Write(" = ");
            //        Initialiser.GenerateC(writer);
            //    }
            //}
        }

        public Modifier Modifier {
            get;
            set;
        }

        public Expression Type {
            get;
            set;
        }

        //public TypeStyle Style {
        //    get;
        //    set;
        //}

        /// <summary>
        /// 获取当前 var 语句定义的所有变量。
        /// </summary>
        public List<VariableDeclaration> Variables {
            get;
            set;
        }

        public override void Write(IndentedTextWriter writer) {

            writer.Write(Modifier.GetName());

            if (Type != null) {
                Type.Write(writer);
            } else {
                writer.Write("var");
            }

            //switch (Style) {
            //    case TypeStyle.Type:
            //        Type.Write(writer);
            //        break;
            //    case TypeStyle.Var:
            //        writer.Write("var");
            //        break;
            //    case TypeStyle.Const:
            //        writer.Write(writer);
            //        break;
            //}

            bool appendComma = false;
            foreach (VariableDeclaration vd in Variables) {
                if (appendComma) {
                    writer.Write(',');
                } else {
                    appendComma = true;
                }

                writer.Write(' ');
                vd.Write(writer);
            }

        }

        //[System.Diagnostics.DebuggerStepThrough]
        //public override void Accept(IAstVisitor visitor) {
        //    visitor.VisitVariableStatement(this);
        //}

        //public override void GenerateC(IndentedTextWriter writer) {
        //    writer.Write(Type.Name);
        //    writer.Write(' ');


        //    bool hasComma = false;
        //    foreach (VariableDeclaration vd in Variables) {
        //        if (hasComma) {
        //            writer.Write(',');
        //            writer.Write(' ');
        //        } else {
        //            hasComma = true;
        //        }

        //        vd.GenerateC(writer);
        //    }

        //    writer.Write(';');
        //}
    }

    /// <summary>
    /// 空语句。
    /// </summary>
    public class EmptyStatement : Statement {

        public override Location EndLocation {
            get {
                return StartLocation;
            }
            set {
                StartLocation = value;
            }
        }

        public override bool IsEmpty {
            get {
                return true;
            }
        }

        //[System.Diagnostics.DebuggerStepThrough]
        //public override void Accept(IAstVisitor visitor) {
        //    visitor.VisitEmptyStatement(this);
        //}

        public override void Write(IndentedTextWriter writer) {
            
        }
    }

    /// <summary>
    /// 表示一个分号。
    /// </summary>
    public class Semicolon : EmptyStatement {

        public override Location EndLocation {
            get {
                return StartLocation + 1;
            }
            set {
                StartLocation = value - 1;
            }
        }

        public override void Write(IndentedTextWriter writer) {
            writer.Write(';');
        }

        //[System.Diagnostics.DebuggerStepThrough]
        //public override void Accept(IAstVisitor visitor) {
        //    visitor.VisitSemicolon(this);
        //}
    }

    /// <summary>
    /// 表示一个层语句。
    /// </summary>
    public class LabelledStatement : Statement {

        public string Label {
            get;
            set;
        }

        public Statement Statement {
            get;
            set;
        }

        public override Location EndLocation {
            get {
                return Statement.EndLocation;
            }
            set {
                Statement.EndLocation = value;
            }
        }

        public override void Write(IndentedTextWriter writer) {
            writer.Indent--;
            writer.Write(Label);
            writer.Write(':');
            writer.WriteLine();
            writer.Indent++;
            Statement.Write(writer);
        }

        //[System.Diagnostics.DebuggerStepThrough]
        //public override void Accept(IAstVisitor visitor) {
        //    visitor.VisitLabelledStatement(this);
        //}
    }

    #endregion

    #region SelectionStatement

    /// <summary>
    /// 表示一个选择语句。
    /// </summary>
    public abstract class SelectionStatement : Statement {

    }

    /// <summary>
    /// 表示一个 if 语句。
    /// </summary>
    public class IfStatement : SelectionStatement {

        /// <summary>
        /// 获取条件。
        /// </summary>
        public Expression Condition {
            get;
            set;
        }

        /// <summary>
        /// 获取当前的则的部分。
        /// </summary>
        public Statement Then {
            get;
            set;
        }

        /// <summary>
        /// 获取当前的否则的部分。
        /// </summary>
        public Statement Else {
            get;
            set;
        }

        public override void Write(IndentedTextWriter writer) {
            writer.Write("if (");
            Condition.Write(writer);
            writer.WriteLine(")");
            writer.Indent++;
            Then.Write(writer);
            writer.Indent--;

            if (Else != null) {
                writer.Write(" else ");
                writer.Indent++;
                Else.Write(writer);
                writer.Indent--;
            }

        }

        //[System.Diagnostics.DebuggerStepThrough]
        //public override void Accept(IAstVisitor visitor) {
        //    visitor.VisitIfStatement(this);
        //}


        //public override void GenerateC(IndentedTextWriter writer) {
        //    writer.WriteSingleLine("if (");
        //    Condition.GenerateC(writer);
        //    writer.WriteLine(")");
        //    writer.Indent();
        //    Then.GenerateC(writer);
        //    writer.UnIndent();
        //    writer.WriteIndent();

        //    if (!Else.IsEmpty) {
        //        writer.Write(" else ");
        //        writer.Indent();
        //        Else.GenerateC(writer);
        //        writer.UnIndent();
        //    }

        //}
    }

    /// <summary>
    /// 表示一个 switch 语句。
    /// </summary>
    public class SwitchStatement : SelectionStatement {

        /// <summary>
        /// 表示一个 Case 层。
        /// </summary>
        public class CaseClause : Node {

            /// <summary>
            /// 获取当前的全部语句。
            /// </summary>
            public List<Statement> Statements {
                get;
                set;
            }

            /// <summary>
            /// 获取层。
            /// </summary>
            public Expression Label {
                get;
                set;
            }

            /// <summary>
            /// 获取是否为默认的case。
            /// </summary>
            public bool IsDefault {
                get {
                    return Label == null;
                }
            }

            public override void Write(IndentedTextWriter writer) {
                if (IsDefault) {
                    writer.Write("default");
                } else {
                    writer.Write("case ");
                    Label.Write(writer);
                }
                writer.WriteLine(": ");
                writer.Indent++;
                foreach (Statement st in Statements) {
                    st.Write(writer);
                }
                writer.Indent--;
            }

            //[System.Diagnostics.DebuggerStepThrough]
            //public override void Accept(IAstVisitor visitor) {
            //    visitor.VisitCaseClause(this);
            //}

            //public override void GenerateC(IndentedTextWriter writer) {

            //}

        }

        /// <summary>
        /// 获取选项。
        /// </summary>
        public List<CaseClause> Cases {
            get;
            set;
        }

        public Expression Condition {
            get;
            set;
        }

        public override void Write(IndentedTextWriter writer) {
            writer.Write("switch (");
            Condition.Write(writer);
            writer.WriteLine(") {");
            writer.Indent++;

            foreach (CaseClause aa in Cases) {
                aa.Write(writer);
                writer.WriteLine();
            }

            writer.Indent--;
            writer.WriteLine("}");

        }

        //[System.Diagnostics.DebuggerStepThrough]
        //public override void Accept(IAstVisitor visitor) {
        //    visitor.VisitSwitchStatement(this);
        //}
    }

    #endregion

    #region IterationStatement

    /// <summary>
    /// 表示一个循环语句。
    /// </summary>
    public abstract class IterationStatement : Statement {

        /// <summary>
        /// 获取条件。
        /// </summary>
        public Expression Condition {
            get;
            internal set;
        }

        /// <summary>
        /// 获取主体。
        /// </summary>
        public Statement Body {
            get;
            internal set;
        }

        public override Location EndLocation {
            get {
                return Body.EndLocation;
            }
            set {
                Body.EndLocation = value;
            }
        }

    }

    /// <summary>
    /// 表示一个While语句。
    /// </summary>
    public class WhileStatement : IterationStatement {

        public override void Write(IndentedTextWriter writer) {
            writer.Write("while(");
            Condition.Write(writer);
            writer.Write(')');
            writer.Indent++;
            Body.Write(writer);
            writer.Indent--;
        }
        
        //[System.Diagnostics.DebuggerStepThrough]
        //public override void Accept(IAstVisitor visitor) {
        //    visitor.VisitWhileStatement(this);
        //}

    }

    /// <summary>
    /// 表示一个Do-While语句。
    /// </summary>
    public class DoWhileStatement : IterationStatement {

        public override void Write(IndentedTextWriter writer) {
            writer.WriteLine("do {");
            writer.Indent++;
            Body.Write(writer);
            writer.Indent--;
            writer.WriteLine("} while(");
            Condition.Write(writer);
            writer.Write(")");
        }

        //[System.Diagnostics.DebuggerStepThrough]
        //public override void Accept(IAstVisitor visitor) {
        //    visitor.VisitDoWhileStatement(this);
        //}
    }

    /// <summary>
    /// 表示一个For语句。
    /// </summary>
    public class ForStatement : IterationStatement {

        /// <summary>
        /// 获取初始化语句。
        /// </summary>
        public Statement InitStatement {
            get;
            private set;
        }

        /// <summary>
        /// 获取下一次语句。
        /// </summary>
        public Expression NextExpression {
            get;
            private set;
        }

        public override void Write(IndentedTextWriter writer) {
            writer.Write("for(");
            InitStatement.Write(writer);
            writer.Write(';');
            Condition.Write(writer);
            writer.Write(';');
            NextExpression.Write(writer);
            writer.Write(")");

            Body.Write(writer);
        }

        //[System.Diagnostics.DebuggerStepThrough]
        //public override void Accept(IAstVisitor visitor) {
        //    visitor.VisitForStatement(this);
        //}
    }

    /// <summary>
    /// 表示一个For-In语句。
    /// </summary>
    public class ForInStatement : IterationStatement {

        /// <summary>
        /// 获取Each表达式。
        /// </summary>
        public Statement Each {
            get;
            set;
        }

        public override void Write(IndentedTextWriter writer) {
            writer.Write("for(");

            Each.Write(writer);
            writer.Write(" in ");
            Condition.Write(writer);
            writer.Write(")");

            Body.Write(writer);
        }

        //[System.Diagnostics.DebuggerStepThrough]
        //public override void Accept(IAstVisitor visitor) {
        //    visitor.VisitForInStatement(this);
        //}
    }

    /// <summary>
    /// 表示一个For-In语句。
    /// </summary>
    public class ForToStatement : IterationStatement {

        /// <summary>
        /// 获取Each表达式。
        /// </summary>
        public Statement Each {
            get;
            private set;
        }

        public override void Write(IndentedTextWriter writer) {
            writer.Write("for(");

            Each.Write(writer);
            writer.Write(" to ");
            Condition.Write(writer);
            writer.Write(")");

            Body.Write(writer);
        }

        //[System.Diagnostics.DebuggerStepThrough]
        //public override void Accept(IAstVisitor visitor) {
        //    visitor.VisitForInStatement(this);
        //}
    }

    #endregion

    #region JumpStatement

    /// <summary>
    /// 表示一个跳转语句。
    /// </summary>
    public abstract class JumpStatement : Statement {

    }

    /// <summary>
    /// 表示一个Continue语句。
    /// </summary>
    public class ContinueStatement : JumpStatement {

        /// <summary>
        /// 获取层。
        /// </summary>
        public string Label {
            get;
            set;
        }

        public override void Write(IndentedTextWriter writer) {
            writer.Write("continue");
            if (Label != null) {
                writer.Write(' ');
                writer.Write(Label);
            }

            writer.WriteLine();
        }

        //[System.Diagnostics.DebuggerStepThrough]
        //public override void Accept(IAstVisitor visitor) {
        //    visitor.VisitContinueStatement(this);
        //}
    }

    /// <summary>
    /// 表示一个Break语句。
    /// </summary>
    public class BreakStatement : JumpStatement {

        /// <summary>
        /// 获取层。
        /// </summary>
        public string Label {
            get;
            set;
        }

        public override void Write(IndentedTextWriter writer) {
            writer.Write("break");
            if (Label != null) {
                writer.Write(' ');
                writer.Write(Label);
            }

            writer.WriteLine();
        }

        //[System.Diagnostics.DebuggerStepThrough]
        //public override void Accept(IAstVisitor visitor) {
        //    visitor.VisitBreakStatement(this);
        //}
    }

    /// <summary>
    /// 表示一个Continue语句。
    /// </summary>
    public class GotoStatement : JumpStatement {

        /// <summary>
        /// 获取层。
        /// </summary>
        public string Label {
            get;
            set;
        }

        public override void Write(IndentedTextWriter writer) {
            writer.Write("goto ");
            writer.Write(Label);
            writer.WriteLine();
        }

        //[System.Diagnostics.DebuggerStepThrough]
        //public override void Accept(IAstVisitor visitor) {
        //    visitor.VisitContinueStatement(this);
        //}
    }

    /// <summary>
    /// 表示一个Return语句。
    /// </summary>
    public class ReturnStatement : JumpStatement {

        /// <summary>
        /// 获取表达式。
        /// </summary>
        public Expression Expression {
            get;
            set;
        }

        /// <summary>
        /// 获取结束位置。
        /// </summary>
        /// <value></value>
        public override Location EndLocation {
            get {
                return Expression == null ? StartLocation + 6 : Expression.EndLocation;
            }
        }

        public override void Write(IndentedTextWriter writer) {
            writer.Write("return");
            if (Expression != null) {
                writer.Write(' ');
                Expression.Write(writer);
            }

            writer.WriteLine();
        }

        //[System.Diagnostics.DebuggerStepThrough]
        //public override void Accept(IAstVisitor visitor) {
        //    visitor.VisitReturnStatement(this);
        //}
    }

    /// <summary>
    /// 表示一个Throw表达式。
    /// </summary>
    public class ThrowStatement : JumpStatement {

        /// <summary>
        /// 获取表达式。
        /// </summary>
        public Expression Expression {
            get;
            set;
        }

        /// <summary>
        /// 获取结束位置。
        /// </summary>
        /// <value></value>
        public override Location EndLocation {
            get {
                return Expression == null ? StartLocation + 5 : Expression.EndLocation;
            }
        }

        public override void Write(IndentedTextWriter writer) {
            writer.Write("throw");
            if (Expression != null) {
                writer.Write(' ');
                Expression.Write(writer);
            }

            writer.WriteLine();
        }

        //[System.Diagnostics.DebuggerStepThrough]
        //public override void Accept(IAstVisitor visitor) {
        //    visitor.VisitThrowStatement(this);
        //}
    }

    #endregion

    #region Other Statement

    /// <summary>
    /// 表示一个Try语句。
    /// </summary>
    public class TryStatement : Statement {

        public class CatchClause : Node {

            public List<VariableStatement.VariableDeclaration> Conditions {
                get;
                set;
            }

            public Statement Statement {
                get;
                set;
            }

            public override void Write(IndentedTextWriter writer) {
                
            }
        }

        /// <summary>
        /// 获取 try 语句块。
        /// </summary>
        public Statement TryClause {
            get;
            set;
        }

        /// <summary>
        /// 获取 try 语句块。
        /// </summary>
        public List<CatchClause> CatchClauses {
            get;
            set;
        }

        /// <summary>
        /// 获取 finally 语句块。
        /// </summary>
        public Statement FinallyClause {
            get;
            set;
        }

        public override Location StartLocation {
            get {
                return TryClause.StartLocation;
            }
            set {
                TryClause.StartLocation = value;
            }
        }

        public override Location EndLocation {
            get {
                if (FinallyClause != null) {
                    return FinallyClause.EndLocation;
                }

                if (CatchClauses.Count > 0) {
                    return CatchClauses[CatchClauses.Count - 1].EndLocation;
                }


                return TryClause.EndLocation;
            }
            set {

                if (FinallyClause != null) {
                    FinallyClause.EndLocation = value;
                } else if (CatchClauses.Count > 0) {
                    CatchClauses[CatchClauses.Count - 1].EndLocation = value;
                } else {
                    TryClause.EndLocation = value;
                }
            }

        }

        public override void Write(IndentedTextWriter writer) {
            writer.Write("try...");
        }
    }

    /// <summary>
    /// 表示一个可调试语句。
    /// </summary>
    public class LockStatement : Statement {

        public Expression Condition {
            get;
            set;
        }

        public Expression Body {
            get;
            set;
        }

        /// <summary>
        /// 获取结束位置。
        /// </summary>
        /// <value></value>
        public override Location EndLocation {
            get {
                return Body.EndLocation;
            }
        }

        public override void Write(IndentedTextWriter writer) {
            writer.Write("lock (");
            Condition.Write(writer);
            writer.Write(")");
            Body.Write(writer);
        }

        //[System.Diagnostics.DebuggerStepThrough]
        //public override void Accept(IAstVisitor visitor) {
        //    visitor.VisitDebuggerStatement(this);
        //}
    }

    /// <summary>
    /// 表示一个可调试语句。
    /// </summary>
    public class LetStatement : Statement {

        public Statement InitStatement {
            get;
            set;
        }

        public Statement Body {
            get;
            set;
        }

        /// <summary>
        /// 获取结束位置。
        /// </summary>
        /// <value></value>
        public override Location EndLocation {
            get {
                return Body.EndLocation;
            }
        }

        public override void Write(IndentedTextWriter writer) {
            writer.Write("let (");
            InitStatement.Write(writer);
            writer.Write(")");
            Body.Write(writer);
        }

        //[System.Diagnostics.DebuggerStepThrough]
        //public override void Accept(IAstVisitor visitor) {
        //    visitor.VisitDebuggerStatement(this);
        //}
    }

    /// <summary>
    /// 表示一个可调试语句。
    /// </summary>
    public class DebuggerStatement : Statement {

        public Expression Condition {
            get;
            set;
        }

        /// <summary>
        /// 获取结束位置。
        /// </summary>
        /// <value></value>
        public override Location EndLocation {
            get {
                return Condition == null ? StartLocation + 8 : Condition.EndLocation;
            }
        }

        public override void Write(IndentedTextWriter writer) {
            writer.Write("debugger");
            if (Condition != null) {
                writer.Write(' ');
                Condition.Write(writer);
            }

            writer.WriteLine();
        }

        //[System.Diagnostics.DebuggerStepThrough]
        //public override void Accept(IAstVisitor visitor) {
        //    visitor.VisitDebuggerStatement(this);
        //}
    }

    #endregion

}
